local desc_zshh_mode = [[
  # 末日人机简介
  ___

  胜利条件：玩家通关第30层。

  失败条件：玩家全部死亡或者投降。玩家自由选将不在白名单列表。敌对人机总数/玩家总数小于等于1。

  规则：继承巅峰神塔玩法包括选将、卡牌、扩展包、奖励选项等。

  新增：
  
    商店新增卡牌扩展包：（已失效）
    
    【基本】卡包（15张杀3种属性均分。15张闪，10张桃，10张酒）、（已失效）
    
    【锦囊】卡包（5无中，5顺，5决斗，5无懈，5拆，3乐，3兵，3借刀，4五谷，4南蛮，4万箭，4桃园）（已失效）

    商店新增药水：
    
    【恢复】药水（恢复一半的损失体力值）、【欲望】药水（摸5张牌）。

  修改：
  
    最后一关。敌对人机全部为最强神将。浦沅商店遇见概率和次数重新调整，浦沅商店技能分别为6种随机的【进攻】技能和【防御】技能。

  也许bug等你发现。。。

]]
local EndLessPractice = require "packages/lang/EndLessPractice"

--是否开启写入武将白名单
local ISwrite = false
--开启测试
local IStest = false
--玩家测试武将
local TESTgen = "mouxusheng"
--测试AI武将（避免自由选）
local TESTgens = {"guozhao","m_ex__liaohua","zhangfen","xielingyu","zhouyi","ol__tengfanglan","dongyun","l__zhangliao","ex__simayi","ol_ex__zhangjiao","ty_ex__zhuran","l__lvbu","ty__yanghu","zhaotongzhaoguang","joy__xunyou","miniex__huangyueying","ty__yanghu","joy__xunyou","godzhaoyun","js__guanyu","lvlingqi","dukui","ty_ex__wuyi","ol_ex__sunjian","xizhicai","qinmi","godganning","ty__chenlin","ex__ganning","yuejiu","caomao","ty__lidian","ol__luyusheng","godganning","ty_ex__caozhi","zhaotongzhaoguang"}
--精选热门武将不必自由选
local HOTgenerals = {"js__liubei","qinmi","ty__caochun","ol__yanghu","l__zhangliao","m_ex__xusheng","ol__huangzu","mou__machao","os_ex__guohuai","liyixiejing"}
--过滤其他卡组（只允许白名单的卡组加入牌堆）
local WHILEcards = {"standard","standard_cards","maneuvering","lang_cards","tenyear_token","mobile_derived","ol_token","overseas_token"}
--保留玩家本模式重要的标记
local SAVEmarks = {"curlayerphase","@slash_dmg","@trick_dmg","@pdlbox","@gold_num","@df_lingxin","@shieldnum","@slash_num"}

--初始化游戏数据
local initGameData = {
  i_layer = 1,--初始关卡
  t_layer = 30,--总关卡
  initgold = 40,--初始金币
  goldpower = 2.5,--获得随机金币*倍率
  maxctiwin = 2,--连胜最多层数即中断当前玩家阶段
  lordslayer = 7,--层主队友+1需要每几层
  lordsperup = 8,--层主队友成长一次需要每几层
  laygetskill_n = 7,--层主每过几关获得技能，包括体力上限
  rewd_intval = {{10,1,4},{20,2,5},{29,3,6}}, --关卡选项变化（可以多选与加选）
  layownskills = {mashu = 3,langxi = 15,liji = 29}, --层主关卡技能
  rewards = {gaingold=0.1,skills = 0.1,maxhp = 0.1,lingxin = 0.1,magicbox=0.1,extraslash_num=0.1,angelbless=0.1,slash_dmg_sel=0.1,trick_dmg_sel=0.1,shieldnum = 0.1},--玩家奖励概率配置
  rulename = "#zshh_rule", --游戏模式名
  meetpuyuan = {rate = 0.15,meet={3,10}}, --第一个值是每次概率上升值，第二个是遇见次数限制[最多次数，第x层数重新刷新最多次数]
  initshopskills = 6
}
-- local isRewardBeforeNext = function(layer)

-- end

local zshh_getLogic = function()
  local zshh_logic = GameLogic:subclass("zshh_logic")


  function GameLogic:prepareForStart()
    local room = self.room
    local players = room.players
    self:addTriggerSkill(GameRule)
    for _, trig in ipairs(Fk.global_trigger) do
      if trig.name ~= "mobile_effect" then  --关闭手杀特效
        self:addTriggerSkill(trig)
      end
    end
    self.room:sendLog{ type = "$GameStart" }
  end

  function zshh_logic:prepareDrawPile()
    local room = self.room
    --重新过滤卡组
    local filterCardIds = {}
    local excepts = {"crossbow","indulgence","supply_shortage","lightning"} -- 删除一些卡组
    local allCardIds = Fk:getAllCardIds()
    for i = 1, #allCardIds do
      local id = allCardIds[i]
      local card = Fk:getCardById(id)
      if card then
        if card.is_derived then
          table.insert(room.void, id)
          room:setCardArea(id, Card.Void, nil)
        else
          if table.contains(WHILEcards,card.package.name) then
            if not table.contains(excepts,card.trueName) then
              table.insert(filterCardIds,id)
            end
          end
        end
      end
    end
    local seed = math.random(2 << 32 - 1)
    table.shuffle(filterCardIds,seed)
    room.draw_pile = filterCardIds
    for _, id in ipairs(room.draw_pile) do
      room:setCardArea(id, Card.DrawPile, nil)
    end
    room:doBroadcastNotify("PrepareDrawPile", seed)
  end

  function zshh_logic:assignRoles()
    local room = self.room
    local n = #room.players
    local roles = self.role_table[n]
    table.shuffle(roles)
    local bots_t = {}
    local players_t = {}
    for i = 1, n do
      local p = room.players[i]
      if p.id < 0 then
        table.insert(bots_t,{p.id,i})
      else
        table.insert(players_t,{p.id,i})
      end
    end
    local botsrand_t = table.random(bots_t)
    local bot_player = room.players[botsrand_t[2]]
    bot_player.role = "lord"
    bot_player.role_shown = true
    room:broadcastProperty(bot_player, "role")
    local loyalists = (n == 5 or n == 6) and 3 or 4
    local loyalistnum = 0
    for i = 1, n do
      local p = room.players[i]
      if p.role ~= "lord" then
        if p.id < 0 then
          if loyalistnum < loyalists then
            p.role = "loyalist"
            loyalistnum = loyalistnum + 1
          else
            p.role = "rebel"
          end 
        else
          p.role = "rebel"
        end
        room:setPlayerProperty(p, "role_shown", true)
        room:broadcastProperty(p, "role")
      end
    end
  end

  function zshh_logic:chooseGenerals()
    local room = self.room
    local lord = room:getLord()
    room.current = lord
    local nonlord = room.players

    self.endlPrac = nil
    self.endlPrac = EndLessPractice:new()
    self.endlPrac.all_generals = {{},{},{}}
    self.endlPrac.clone_generals = {{},{},{}}
    
    local io_obj
    if ISwrite then
      io_obj = io.open("packages\\lang\\white_generals.txt","w")
    end
    local diffStrongGens = GensLimts:getDiffStrongGens()
    for i, difflays in ipairs(diffStrongGens) do
      for _,gen in ipairs(difflays) do
        local g = Fk.generals[gen]
        if g then
          table.insert(self.endlPrac.all_generals[i],g.name)
          table.insert(self.endlPrac.clone_generals[i],g.name)
          if ISwrite then
            local str = Fk:translate(g.name).."..来源于扩展包:".."【"..Fk:translate(g.package.name).."】".."\n"
            io_obj:write(str)
          end
        end
      end
    end
    if ISwrite then io_obj:close() end

    local clohotgens = table.random(HOTgenerals,6)
    for i=1,3 do
      table.shuffle(self.endlPrac.all_generals[i])
      table.insertTable(clohotgens,table.random(self.endlPrac.all_generals[i],4))
    end
    table.shuffle(clohotgens)
    local generalNum = 18
    local testgs = table.clone(TESTgens)
    -- local deadname,aliveone = "blank_shibing",true
    local req = Request:new(nonlord, "AskForGeneral")

    for i, p in ipairs(nonlord) do
      local arg = {}
      if p.id > 0 then
        for i = 1, generalNum do
          local g = clohotgens[i]
          if g then table.insert(arg, g) end
        end
        if IStest then table.insert(arg,  testgs) end
        req:setData(p, { arg, 1 })
        req:setDefaultReply(p, table.random(arg, 1))
  
      else
        if p.role == "loyalist" then
          table.insert(arg, "blank_shibing")
        else
          local autoselgen = (IStest and #testgs > 0) and table.remove(testgs,1) or table.remove(self.endlPrac.all_generals[1],1)
          table.insert(arg, autoselgen)
        end
        req:setData(p, { arg, 1 })
        req:setDefaultReply(p, table.random(arg, 1))
      end
    end

    for _, p in ipairs(nonlord) do
      local result = req:getResult(p)
      local general, deputy = result[1], result[2]
      room:findGeneral(general)
      room:findGeneral(deputy)
      room:prepareGeneral(p, general, deputy)
    end

    room:askForChooseKingdom(nonlord)
    for _, p in ipairs(nonlord) do
      room:broadcastProperty(p, "general")
      if p.role == "lord" then
        room:broadcastProperty(p, "kingdom")
      end
    end
  end
  return zshh_logic
end

--巅峰神塔模式
local zshh_rule = fk.CreateTriggerSkill{
  name = "#zshh_rule",
  priority = 0.001,
  refresh_events = {fk.GameStart,fk.BuryVictim,fk.GameOverJudge,fk.TurnStart,fk.DrawNCards},
  can_refresh = function(self, event, target, player, data)
    if event == fk.TurnStart then
      return player == target
    else
      return player.id < 0 and player.role == "lord"
    end
  end,
  on_refresh = function(self, event, target, player, data)
    local room = player.room
    if event == fk.BuryVictim then
      room:setTag("SkipGameRule", true)
      local body = room:getPlayerById(data.who)
      local lord = player.room:getLord()
      local logic = lord.room.logic
      local endlPrac = logic.endlPrac
      local allgenerals = endlPrac.all_generals
      if not target.dying then return end
      if not allgenerals or (type(allgenerals[1]) == "table" and #allgenerals[1] == 0) or ((type(allgenerals[1]) == "string" and #allgenerals == 0)) then
        room:doBroadcastNotify("ShowToast", "人机将池耗尽")
        room:gameOver("rebel")
        return
      end
      --过了所有关卡胜利
      local curlayer = endlPrac:getLayer()
      if curlayer >= endlPrac.totallayer then
        room:doBroadcastNotify("ShowToast", endlPrac.totallayer.."层！！爬塔成功！！可喜可贺！！！")
        room:gameOver("rebel")
        return
      end
      --层主及队友都死亡
      --层主忠臣队友阵亡处理
      if body.role ~= "rebel" then
        endlPrac:bury(body)
        local lords = table.filter(room.alive_players,function(pr) return pr.id < 0 and GensLimts:isSameCamp(body,pr) end)
        if #lords > 0 then
          local draw = 2 + math.floor(curlayer / 10)
          endlPrac:drawCardsByCamp(draw,lords)
          return
        end
      else
        --玩家阵亡处理
        if body.role == "rebel" then
          --守护天使效果
          if body:getMark("@@guardangle") > 0 then
            endlPrac:bury(body,SAVEmarks)
            room:revivePlayer(body, false)
            room:drawCards(body, 4 + (math.floor(curlayer/10) * 2),self.name)
            if room.current.role ~= body.role then
              endlPrac:endWhoPhase()
            end
            return
          end
          --全部阵亡结算
          local alivehumans = endlPrac:getAliveHumans()
          if #alivehumans <= 0 then
            room:doBroadcastNotify("ShowToast", "全部阵亡，爬塔层数"..curlayer)
            room:gameOver("lord")
            return
          end
          --玩家阵亡处理
          endlPrac:bury(body,SAVEmarks)
          endlPrac:otherPlayersDraw(2+(math.floor(curlayer/10)*2))
          room:doBroadcastNotify("ShowToast", Fk:translate(body.general) .."阵亡，别放弃还有机会复活")
          return
        end
      end
      ----------------------------执行下一层逻辑--------------------------
      --boss死亡后获得其中一个技能
      local defeat
      if data.damage and data.damage.from and not data.damage.from.dead then
        defeat = data.damage.from
      end
      body = endlPrac:getLayerOwner()
      local otherplayers = endlPrac:getOPlayers(body)
      local lords = {}
      local rebels = -1
      for _,pr in ipairs(room.players) do
        if pr.id < 0 and GensLimts:isSameCamp(body,pr) and body.id ~= pr.id then table.insert(lords,pr) end
        if pr.id > 0 then rebels = rebels + 1 end
      end

      local relifenum = math.floor((curlayer + 1) / initGameData.lordslayer) + rebels 
      if #lords > 0 and relifenum > 0 then
        local boss
        if not allgenerals[math.floor((curlayer + 1) / 10) + 1] then
          boss = {"godzhangjiao","godsunce","godganning","godtaishici","godmachao"}
          table.shuffle(boss)
        end
        endlPrac:reLayerFriends(lords,math.min(relifenum,4),boss)
        if boss and #boss > 0 then
          endlPrac.godboss = boss
        end
      end
      --层主死亡层数+1并复活加强
      endlPrac:removeLayerBoss(defeat)
      endlPrac:changeLayer(1)
      --清除相关技能
      endlPrac:removeRelateSkills(body)
      --转变武将且复活
      local layer = endlPrac:getLayer()
      local haveboss = endlPrac:getLayerBoss()
      local newgeneral = endlPrac:changeGeneral(body,haveboss)
      if not newgeneral then
        room:doBroadcastNotify("ShowToast", "将池耗尽")
        room:gameOver("rebel")
        return
      end
      --删除复活前技能
      endlPrac:removeOldSkills(newgeneral,body)
      --刷新最大maxhp与hp
      local cal_add = math.floor(layer / initGameData.laygetskill_n)
      if haveboss then
        cal_add = math.floor(cal_add * 2.5)
      end
      if cal_add > 0 then
        endlPrac:updateMax(body,cal_add)
      end
      --获得关卡技能
      endlPrac:getLaySkills(body)
      --层主或层队友每过n关获得随机技能
      local n = endlPrac:getRskiNum()
      if n > 0 then
        endlPrac:getRandSkills(n,body)
      end
      --刷新层数
      endlPrac:updateLayer(body,"@wj_layer")
      --通知其他角色层数
      endlPrac:notifyLayer("curlayerphase")
      --摸等量手牌
      endlPrac:drawByRelife(body)
      --------------------------------------------------------------------
      -----------------------玩家处理--------------------------------------
      --------------------------------------------------------------------
      if rebels > 0 and math.floor((curlayer + 1) / initGameData.lordslayer) > math.floor(curlayer / initGameData.lordslayer) and relifenum <= 4 and rebels + 1 ~= 3 then
        endlPrac:relifeAIRebels()
      end
      endlPrac:gainRandGold()
      endlPrac:meetPuYuan()
      endlPrac:addContiWin(1)
      --每3+（层数/10）关获得一次奖励
      if layer % 5 ~= 0 then
        --连胜超过一定回合结束当前阶段
        endlPrac:handleContiWin()
        return
      end
      --玩家潘多拉技能重置
      endlPrac:resetPdlSkills()
      --随机的奖励选项
      --开始选择
      endlPrac:layerRewards()
      --召唤潘多拉
      -- local call_n = 6 * #otherplayers
      -- endlPrac:callPanduola(body,call_n)
      --连胜超过一定回合结束当前阶段
      endlPrac:handleContiWin()
    elseif event == fk.GameStart then
      local room = player.room
      local logic = player.room.logic
      local endlPrac = logic.endlPrac
      local allgenerals = endlPrac.all_generals

      local otherplayers = endlPrac:getOPlayers(player)
      local humans,lordloyas = 0,0
      for _, pr in ipairs(room.players) do
        if pr.id > 0 then
          humans = humans + 1
        else
          if pr.role ~= "rebel" then
            lordloyas = lordloyas + 1
          end
        end
      end
      --规则限制
      if not endlPrac or (type(allgenerals[1]) == "table" and #allgenerals[1] == 0) or ((type(allgenerals[1]) == "string" and #allgenerals == 0)) then
        room:doBroadcastNotify("ShowToast", "模式或者人机无将池错误")
        room:gameOver(player.role)
        return
      end
      if humans > 3 or lordloyas / humans <= 1 then
        room:doBroadcastNotify("ShowToast", "玩家数量过多不符合游戏规则")
        room:gameOver(player.role)
        return
      end
      local gamedata = table.clone(initGameData)
      endlPrac:initData(player,gamedata)
      local introduces = {"justsoso","justbored","justlike"}
      table.shuffle(introduces)
      for _, p in ipairs(room.players) do
        if p.id > 0 then
          if not IStest and not GensLimts:isGensPools(allgenerals,p.general) then
            room:doBroadcastNotify("ShowToast", Fk:translate(p.general).."不在白名单。游戏结束。具体白名单请看835104528群文件")
            room:gameOver(player.role)
            return
          end 
          local reply = room:askForCustomDialog(p,self.name,"packages/lang/qml/DialogChoiceBox.qml",{"author_says","dfst_introduce",introduces,"hxfc_author"})
          if reply == "justsoso" then 
            room:doBroadcastNotify("ShowToast", "幻想风车：看来我还需要考虑其他模式.....") 
            room:addPlayerMark(p,"@slash_num",1) 
          elseif reply == "justlike" then 
            room:doBroadcastNotify("ShowToast", Fk:translate(p.general).."承蒙喜欢❤") 
            room:addPlayerMark(p,"@slash_num",2)
          end
        else
          if p.role ~= "lord" then 
            if humans - 1 > 0 and p.role == "loyalist" then
              humans = humans - 1
              endlPrac:changeGeneral(p)
            else
              room:killPlayer({ who = p.id }) 
            end
          end
        end
      end
      endlPrac:layerRewards()
    elseif event == fk.GameOverJudge then
      room:setTag("SkipGameRule", true)
    elseif event == fk.TurnStart then
      local room = player.room
      local lord = room:getLord()
      local endlPrac = lord.room.logic.endlPrac
      if endlPrac then endlPrac:setContiWin(0) end
    elseif event == fk.DrawNCards then
      -- local room = player.room
      local endlPrac = player.room.logic.endlPrac
      local haveboss = endlPrac:getLayerBoss()
      if haveboss then
        local layer = endlPrac:getLayer()
        local value = math.ceil(layer / 10) * 2
        data.n = data.n + value
      end
    end
  end,
}
Fk:addSkill(zshh_rule)

local zshh_mode = fk.CreateGameMode{
  name = "zshh_mode",
  minPlayer = 5,
  maxPlayer = 8,
  rule = zshh_rule,
  logic = zshh_getLogic,
  whitelist = table.clone(WHILEcards),
  winner_getter = function(self, victim)
    local room = victim.room
    local alive = table.filter(room.alive_players, function(p)
      return not p.surrendered
    end)
    if #alive ~= 1 then return "" end
    return alive[1].role
  end,
  surrender_func = function(self, playedTime)
    local surrenderJudge = { { text = "time limitation: 10s", passed = playedTime >= 10 } }
    if Self.role ~= "lord" then
      table.insert(surrenderJudge, { text = "1v1: left you alive", passed = true})
    end
    return surrenderJudge
  end,
}

Fk:loadTranslationTable{
  ["zshh_mode"] = "末日人机",
  ["#zshh_rule"] = "末日人机",

  [":zshh_mode"] = desc_zshh_mode,
}

return zshh_mode
